from math import sqrt,cos,sin, pow,pi


EARTH_RADIUS = 6371

def distanceBetween(lat1,lon1,lat2,lon2):
    lat1 = lat1*pi/180
    lon1 = lon1*pi/180
    lat2 = lat2*pi/180
    lon2 = lon2*pi/180
    return EARTH_RADIUS * sqrt(pow(lat2-lat1, 2) + pow((lon2-lon1)*cos((lat1+lat2)/2),2))


def getBoundingBox(centerLat,centerLon,radius):    
    # returns a bouding rectangle
    # [minimum-latitude, minimum-longitude, maximum-latitude, maximum-longitude]
    lat = (float(radius)/float(EARTH_RADIUS)) * 180/pi 
    lng = lat/cos(centerLat * pi/180)
    maxLon = centerLon + (lng * cos(pi * (0/6)))
    maxLat = centerLat + (lat * sin(pi * (0.5)))
    
    minLon = centerLon + (lng * cos(pi * (6/6)))
    minLat = centerLat + (lat * sin(pi * (1.5)))
    
    return [minLat,minLon,maxLat,maxLon]

class CoordinateIteratorResult:
    def __init__(self,bBox,nextLat,nextLon):
        self.bBox = bBox
        self.nextLat = nextLat
        self.nextLon = nextLon

class CoordinateIterator:
    LATITUDE_STEP = 0.01
    LONGITUDE_STEP = 0.03
    
    def __init__(self,prevLat,prevLon,minLat,minLon,maxLat,maxLon):
        self.prevLat = prevLat
        self.prevLon = prevLon
        self.minLat = minLat
        self.minLon = minLon
        self.maxLat = maxLat - CoordinateIterator.LATITUDE_STEP
        self.maxLon = maxLon
    
    def __nextLat(self):
        lat = self.prevLat + CoordinateIterator.LATITUDE_STEP
        if lat <= self.maxLat : return lat
        else:  return self.maxLat  
    
    def __nextLon(self):
        lon = self.prevLon + CoordinateIterator.LONGITUDE_STEP
        if lon <= self.maxLon: return lon
        else: return self.maxLon 
        
    def next(self):
        #returns CoordinateIteratorResult or none if we are done
        # direction: left -> right , down -> up
        
        isMaxLat = self.prevLat == self.maxLat 
        isMaxLon = self.prevLon == self.maxLon 
        
        #if we reached max latitude and longitude, we are done
        if isMaxLat and isMaxLon: return None
        
        #if we reached max longitude, move to the next latitude 
        if isMaxLon:
            #self.prevLat = self.prevLat + CoordinateIterator.LATITUDE_STEP
            self.prevLon = self.minLon  
        
        nextLon = self.__nextLon()
        nextLat = self.__nextLat()
        bBox = [self.prevLat,self.prevLon,nextLat,nextLon]
        if nextLon < self.maxLon: nextLat = self.prevLat
        return CoordinateIteratorResult(bBox,nextLat, nextLon)
        